package com.sydata.common.utils;

import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMException;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;


public class HttpWithSslClientUtils {
    public static Logger logger = LoggerFactory.getLogger(HttpWithSslClientUtils.class);

    public static String sendPostRequestWithSSL(String url, String requestBody, String rootCertificatePath, String clientCertificatePath, String clientKeyPath, String privateKeyPassword) throws Exception {
        // 加载根证书
        X509Certificate rootCertificate = loadCertificate(rootCertificatePath);

        // 加载客户端证书和私钥
        X509Certificate clientCertificate = loadCertificate(clientCertificatePath);
        Key privateKey = loadPrivateKey(clientKeyPath, privateKeyPassword);

        // 创建 SSLContext 并初始化 KeyManagerFactory 和 TrustManagerFactory
        SSLContext sslContext = SSLContext.getInstance("TLS");
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(createKeyStore(clientCertificate, privateKey), null);
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(createTrustStore(rootCertificate));

        // 初始化 SSLContext
        sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

        // 创建 URL 对象
        URL requestUrl = new URL(url);
        HttpsURLConnection connection = (HttpsURLConnection) requestUrl.openConnection();

        // 设置 SSLContext
        connection.setSSLSocketFactory(sslContext.getSocketFactory());

        // 设置请求方法和请求头
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 设置请求体
        try (OutputStream outputStream = connection.getOutputStream()) {
            outputStream.write(requestBody.getBytes());
            outputStream.flush();
        }

        // 发送请求并获取响应
        int responseCode = connection.getResponseCode();
        logger.info("【请求领科DP+ 响应状态】{}",responseCode);

        StringBuilder response = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
        }

        connection.disconnect();

        logger.info("【请求领科DP+ 响应】{}",response);
        return response.toString();
    }

    // 加载证书
    private static X509Certificate loadCertificate(String certificatePath) throws Exception {
        FileInputStream inputStream = new FileInputStream(certificatePath);
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);
        inputStream.close();
        return certificate;
    }

    // 加载私钥文件并转换为 Key 对象
    private static Key loadPrivateKey(String privateKeyPath, String privateKeyPassword) throws Exception {
        FileInputStream inputStream = new FileInputStream(privateKeyPath);
        PEMParser pemParser = new PEMParser(new InputStreamReader(inputStream));

        Object pemObject = pemParser.readObject();
        Key privateKey = null;

        if (pemObject instanceof PEMEncryptedKeyPair) {
            // 处理加密的私钥文件，需要提供密码
            PEMEncryptedKeyPair encryptedKeyPair = (PEMEncryptedKeyPair) pemObject;
            PEMKeyPair keyPair = encryptedKeyPair.decryptKeyPair(new JcePEMDecryptorProviderBuilder().build(privateKeyPassword.toCharArray()));
            privateKey = new JcaPEMKeyConverter().getPrivateKey(keyPair.getPrivateKeyInfo());
        } else if (pemObject instanceof PEMKeyPair) {
            // 处理非加密的私钥文件
            PEMKeyPair keyPair = (PEMKeyPair) pemObject;
            privateKey = new JcaPEMKeyConverter().getPrivateKey(keyPair.getPrivateKeyInfo());
        } else {
            throw new PEMException("Unsupported PEM object: " + pemObject.getClass().getName());
        }

        pemParser.close();
        inputStream.close();

        return privateKey;
    }

    // 创建 KeyStore
    private static KeyStore createKeyStore(X509Certificate certificate, Key privateKey) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(null, null);
        keyStore.setCertificateEntry("certificate", certificate);
        keyStore.setKeyEntry("privateKey", privateKey, null, new java.security.cert.Certificate[]{certificate});
        return keyStore;
    }

    // 创建信任库
    private static KeyStore createTrustStore(X509Certificate rootCertificate) throws Exception {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);
        trustStore.setCertificateEntry("rootCertificate", rootCertificate);
        return trustStore;
    }
}
